<!DOCTYPE html>
<html>
<head>
	<!-- Global site tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id='UA-133422980-2"></script>
	<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());

	  gtag('config', 'UA-133422980-2');
	</script>

	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">

	<title>
		gem5: Memory system 
	</title>

	<!-- SITE FAVICON -->
	<link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/>

	<link rel="canonical" href="http://localhost:4000/documentation/general_docs/memory_system/">
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'>

	<!-- FAVICON -->
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

	<!-- BOOTSTRAP -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

	<!-- CUSTOM CSS -->
	<link rel="stylesheet" href="/css/main.css">
</head>


<body>
	<nav class="navbar navbar-expand-md navbar-light bg-light">
  <a class="navbar-brand" href="/">
		<img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=55px>
	</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <!-- LIST FOR NAVBAR -->
    <ul class="navbar-nav ml-auto">
      <!-- HOME -->
      <li class="nav-item ">
        <a class="nav-link" href="/">Home</a>
      </li>

      <!-- ABOUT -->
			<li class="nav-item dropdown ">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					About
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="/about">About gem5</a>
          <a class="dropdown-item" href="/publications">Publications</a>
          <a class="dropdown-item" href="/governance">Governance</a>
				</div>
			</li>

      <!-- DOCUMENTATION -->
			<li class="nav-item dropdown active">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					Documentation
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
					<!-- Pull navigation from _data/documentation.yml -->
					
            <a class="dropdown-item" href="/documentation">gem5 documentation</a>
					
            <a class="dropdown-item" href="/documentation/learning_gem5/introduction">Learning gem5</a>
					
            <a class="dropdown-item" href="http://doxygen.gem5.org/release/current/index.html">gem5 Doxygen</a>
					
            <a class="dropdown-item" href="/documentation/reporting_problems">Reporting Problems</a>
					
				</div>
			</li>

      <!-- EVENTS -->
			<li class="nav-item dropdown ">
        <a class="nav-link" href="/events/">Events</a>
			</li>

      <!-- CONTRIBUTING -->
      <li class="nav-item ">
        <a class="nav-link" href="/contributing">Contributing</a>
      </li>

      <!-- BLOG -->
      <li class="nav-item ">
        <a class="nav-link" href="/blog">Blog</a>
      </li>

      <!-- SEARCH -->
			<li class="nav-item ">
        <a class="nav-link" href="/search">Search</a>
      </li>
    </ul>
  </div>
</nav>

	<main>
		<div class="sidenav-top">
  <div class="sidenav-brand bg-light">
    <a href="/"><img src="/assets/img/gem5ColorLong.gif" height="55px"></a>
  </div>
  <div class="search">
    <form action="/search" method="get">
      <!-- <label for="search-box"><i class="fa fa-search"></i></label> -->
      <input type="text" name="query">
      <button type="submit" name="submit"><i class="fa fa-search"></i></button>
    </form>
  </div>
</div>
<div class="sidenav">
  <!-- Pull navigation from _data/documentation.yml -->
  
    
    
      <a class="item" href="/documentation" role="button" aria-expanded="false" aria-controls="collapseExample">
        gem5 documentation
      </a>
      <div class="collapse " id="gem5_documentation">
        
      </div>
    
      <a class="item" href="/documentation/general_docs/development/coding_style/" role="button" aria-expanded="false" aria-controls="collapseExample">
        Code Style
      </a>
      <div class="collapse " id="code_style">
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#building" role="button" aria-expanded="false" aria-controls="collapseExample">
        Building
      </a>
      <div class="collapse " id="building">
        
          <a class="subitem " href="/documentation/general_docs/building">Building</a>
        
          <a class="subitem " href="/documentation/general_docs/building/EXTRAS">Building EXTRAS</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#doxygen-docs" role="button" aria-expanded="false" aria-controls="collapseExample">
        Doxygen
      </a>
      <div class="collapse " id="doxygen-docs">
        
          <a class="subitem " href="http://doxygen.gem5.org/develop/index.html">Develop Branch</a>
        
          <a class="subitem " href="http://doxygen.gem5.org/release/v19-0-0-0/index.html">v19.0.0.0</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#fullsystem" role="button" aria-expanded="false" aria-controls="collapseExample">
        Full System
      </a>
      <div class="collapse " id="fullsystem">
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/disks">Creating Disk Images</a>
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/devices">Devices</a>
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/m5term">m5term</a>
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/building_arm_kernel">Building Linux ARM Kernel</a>
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/building_android_m">Building Android Marshmallow</a>
        
          <a class="subitem " href="/documentation/general_docs/fullsystem/guest_binaries">Guest binaries</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#memory_system" role="button" aria-expanded="false" aria-controls="collapseExample">
        Memory System
      </a>
      <div class="collapse show" id="memory_system">
        
          <a class="subitem " href="/documentation/general_docs/memory_system/">Memory System</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/gem5_memory_system">gem5 Memory System</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/replacement_policies">Replacement Policies</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/indexing_policies">Indexing Policies</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/classic-coherence-protocol">Classic memory system coherence</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/classic_caches">Classic caches</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#ruby" role="button" aria-expanded="false" aria-controls="collapseExample">
        Ruby Memory System
      </a>
      <div class="collapse " id="ruby">
        
          <a class="subitem " href="/documentation/general_docs/ruby">Ruby</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/cache-coherence-protocols">Cache Coherence Protocols</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/garnet-2">Garnet 2.0</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/MOESI_CMP_directory">MOESI CMP directory</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/garnet_synthetic_traffic">Garnet Synthetic Traffic</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/slicc">SLICC</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/MI_example">MI example</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/Garnet_standalone">Garnet standalone</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/interconnection-network">Interconnection network</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/MOESI_hammer">MOESI hammer</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/MOESI_CMP_token">MOESI CMP token</a>
        
          <a class="subitem " href="/documentation/general_docs/ruby/MESI_Two_Level">MESI two level</a>
        
          <a class="subitem " href="/documentation/general_docs/memory_system/replacement_policies">Replacement Policies</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#cpu_models" role="button" aria-expanded="false" aria-controls="collapseExample">
        CPU Models
      </a>
      <div class="collapse " id="cpu_models">
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/SimpleCPU">SimpleCPU</a>
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/O3CPU">O3CPU</a>
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/TraceCPU">TraceCPU</a>
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/minor_cpu">Minor CPU Model</a>
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/execution_basics">Execution Basics</a>
        
          <a class="subitem " href="/documentation/general_docs/cpu_models/visualization">Visualization</a>
        
      </div>
    
      <a class="item" href="/documentation/general_docs/m5ops" role="button" aria-expanded="false" aria-controls="collapseExample">
        M5ops
      </a>
      <div class="collapse " id="m5ops">
        
      </div>
    
      <a class="item" href="/documentation/general_docs/checkpoints" role="button" aria-expanded="false" aria-controls="collapseExample">
        Checkpoints
      </a>
      <div class="collapse " id="checkpoints">
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#directed_testers" role="button" aria-expanded="false" aria-controls="collapseExample">
        Directed Testers
      </a>
      <div class="collapse " id="directed_testers">
        
          <a class="subitem " href="/documentation/general_docs/debugging_and_testing/directed_testers/garnet_synthetic_traffic">Garnet Synthetic Traffic</a>
        
          <a class="subitem " href="/documentation/general_docs/debugging_and_testing/directed_testers/ruby_random_tester">Ruby Random Tester</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#debugging" role="button" aria-expanded="false" aria-controls="collapseExample">
        Debugging
      </a>
      <div class="collapse " id="debugging">
        
          <a class="subitem " href="/documentation/general_docs/debugging_and_testing/debugging/trace_based_debugging">Trace-based Debugging</a>
        
          <a class="subitem " href="/documentation/general_docs/debugging_and_testing/debugging/debugger_based_debugging">Debugger-based Debugging</a>
        
          <a class="subitem " href="/documentation/general_docs/debugging_and_testing/debugging/debugging_simulated_code">Debugging Simulated Code</a>
        
          <a class="subitem " href="/documentation/reporting_problems">Reporting Problems</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#architecture_support" role="button" aria-expanded="false" aria-controls="collapseExample">
        Architecture Support
      </a>
      <div class="collapse " id="architecture_support">
        
          <a class="subitem " href="/documentation/general_docs/architecture_support/">Architecture Support</a>
        
          <a class="subitem " href="/documentation/general_docs/architecture_support/arm_implementation/">ARM Implementation</a>
        
          <a class="subitem " href="/documentation/general_docs/architecture_support/isa_parser/">ISA Parser</a>
        
          <a class="subitem " href="/documentation/general_docs/architecture_support/x86_microop_isa/">X86 microop ISA</a>
        
      </div>
    
      <a class="item" href="/documentation/general_docs/thermal_model" role="button" aria-expanded="false" aria-controls="collapseExample">
        Power and Thermal Model
      </a>
      <div class="collapse " id="">
        
      </div>
    
      <a class="item" href="/documentation/general_docs/compiling_workloads/" role="button" aria-expanded="false" aria-controls="collapseExample">
        Compiling Workloads
      </a>
      <div class="collapse " id="compiling_workloads">
        
      </div>
    
      <a class="item" href="/documentation/general_docs/statistics/" role="button" aria-expanded="false" aria-controls="collapseExample">
        Stats Package
      </a>
      <div class="collapse " id="statistics">
        
      </div>
    
    
  
    
  
    
  
    
  
</div>


<div class="container" id="doc-container">
  <div class="edit"><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Edit this page</a></div>
  <b>authors:</b> Jason Lowe-Power<br>
  

  <br>
  <h1 id="memory-system">Memory system</h1>

<p>M5’s new memory system (introduced in the first 2.0 beta release) was
designed with the following goals:</p>

<ol>
  <li>Unify timing and functional accesses in timing mode. With the old
memory system the timing accesses did not have data and just
accounted for the time it would take to do an operation. Then a
separate functional access actually made the operation visible to
the system. This method was confusing, it allowed simulated
components to accidentally cheat, and prevented the memory system
from returning timing-dependent values, which isn’t reasonable for
an execute-in-execute CPU model.</li>
  <li>Simplify the memory system code – remove the huge amount of
templating and duplicate code.</li>
  <li>Make changes easier, specifically to allow other memory
interconnects besides a shared bus.</li>
</ol>

<p>For details on the new coherence protocol, introduced (along with a
substantial cache model rewrite) in 2.0b4, see <a href="classic-coherence-protocol" title="wikilink">Coherence
Protocol</a>.</p>

<h3 id="memobjects">MemObjects</h3>

<p>All objects that connect to the memory system inherit from <code class="highlighter-rouge">MemObject</code>.
This class adds the pure virtual functions <code class="highlighter-rouge">getMasterPort(const
std::string &amp;name, PortID idx)</code> and <code class="highlighter-rouge">getSlavePort(const std::string
&amp;name, PortID idx)</code> which returns a port corresponding to the given name
and index. This interface is used to structurally connect the MemObjects
together.</p>

<h3 id="ports">Ports</h3>

<p>The next large part of the memory system is the idea of ports. Ports are
used to interface memory objects to each other. They will always come in
pairs, with a MasterPort and a SlavePort, and we refer to the other port
object as the peer. These are used to make the design more modular. With
ports a specific interface between every type of object doesn’t have to
be created. Every memory object has to have at least one port to be
useful. A master module, such as a CPU, has one or more MasterPort
instances. A slave module, such as a memory controller, has one or more
SlavePorts. An interconnect component, such as a cache, bridge or bus,
has both MasterPort and SlavePort instances.</p>

<p>There are two groups of functions in the port object. The <code class="highlighter-rouge">send*</code>
functions are called on the port by the object that owns that port. For
example to send a packet in the memory system a CPU would call
<code class="highlighter-rouge">myPort-&gt;sendTimingReq(pkt)</code> to send a packet. Each send function has a
corresponding recv function that is called on the ports peer. So the
implementation of the <code class="highlighter-rouge">sendTimingReq()</code> call above would simply be
<code class="highlighter-rouge">peer-&gt;recvTimingReq(pkt)</code> on the slave port. Using this method we only
have one virtual function call penalty but keep generic ports that can
connect together any memory system objects.</p>

<p>Master ports can send requests and receive responses, whereas slave
ports receive requests and send responses. Due to the coherence
protocol, a slave port can also send snoop requests and receive snoop
responses, with the master port having the mirrored interface.</p>

<h3 id="connections">Connections</h3>

<p>In Python, Ports are first-class attributes of simulation objects, much
like Params. Two objects can specify that their ports should be
connected using the assignment operator. Unlike a normal variable or
parameter assignment, port connections are symmetric: <code class="highlighter-rouge">A.port1 =
B.port2</code> has the same meaning as <code class="highlighter-rouge">B.port2 = A.port1</code>. The notion of
master and slave ports exists in the Python objects as well, and a check
is done when the ports are connected together.</p>

<p>Objects such as busses that have a potentially unlimited number of ports
use “vector ports”. An assignment to a vector port appends the peer to a
list of connections rather than overwriting a previous connection.</p>

<p>In C++, memory ports are connected together by the python code after all
objects are instantiated.</p>

<h3 id="request">Request</h3>

<p>A request object encapsulates the original request issued by a CPU or
I/O device. The parameters of this request are persistent throughout the
transaction, so a request object’s fields are intended to be written at
most once for a given request. There are a handful of constructors and
update methods that allow subsets of the object’s fields to be written
at different times (or not at all). Read access to all request fields is
provided via accessor methods which verify that the data in the field
being read is valid.</p>

<p>The fields in the request object are typically not available to devices
in a real system, so they should normally be used only for statistics or
debugging and not as architectural values.</p>

<p>Request object fields include:</p>

<ul>
  <li>Virtual address. This field may be invalid if the request was issued
directly on a physical address (e.g., by a DMA I/O device).</li>
  <li>Physical address.</li>
  <li>Data size.</li>
  <li>Time the request was created.</li>
  <li>The ID of the CPU/thread that caused this request. May be invalid if
the request was not issued by a CPU (e.g., a device access or a
cache writeback).</li>
  <li>The PC that caused this request. Also may be invalid if the request
was not issued by a CPU.</li>
</ul>

<h3 id="packet">Packet</h3>

<p>A Packet is used to encapsulate a transfer between two objects in the
memory system (e.g., the L1 and L2 cache). This is in contrast to a
Request where a single Request travels all the way from the requester to
the ultimate destination and back, possibly being conveyed by several
different Packets along the way.</p>

<p>Read access to many packet fields is provided via accessor methods which
verify that the data in the field being read is valid.</p>

<p>A packet contains the following all of which are accessed by accessors
to be certain the data is valid:</p>

<ul>
  <li>The address. This is the address that will be used to route the
packet to its target (if the destination is not explicitly set) and
to process the packet at the target. It is typically derived from
the request object’s physical address, but may be derived from the
virtual address in some situations (e.g., for accessing a fully
virtual cache before address translation has been performed). It may
not be identical to the original request address: for example, on a
cache miss, the packet address may be the address of the block to
fetch and not the request address.</li>
  <li>The size. Again, this size may not be the same as that of the
original request, as in the cache miss scenario.</li>
  <li>A pointer to the data being manipulated.
    <ul>
      <li>Set by <code class="highlighter-rouge">dataStatic()</code>, <code class="highlighter-rouge">dataDynamic()</code>, and <code class="highlighter-rouge">dataDynamicArray()</code>
which control if the data associated with the packet is freed
when the packet is, not, with <code class="highlighter-rouge">delete</code>, and with <code class="highlighter-rouge">delete []</code>
respectively.</li>
      <li>Allocated if not set by one of the above methods <code class="highlighter-rouge">allocate()</code>
and the data is freed when the packet is destroyed. (Always safe
to call).</li>
      <li>A pointer can be retrived by calling <code class="highlighter-rouge">getPtr()</code></li>
      <li><code class="highlighter-rouge">get()</code> and <code class="highlighter-rouge">set()</code> can be used to manipulate the data in the
packet. The get() method does a guest-to-host endian conversion
and the set method does a host-to-guest endian conversion.</li>
    </ul>
  </li>
  <li>A status indicating Success, BadAddress, Not Acknowleged, and
Unknown.</li>
  <li>A list of command attributes associated with the packet
    <ul>
      <li>Note: There is some overlap in the data in the status field and
the command attributes. This is largely so that a packet an be
easily reinitialized when nacked or easily reused with atomic or
functional accesses.</li>
    </ul>
  </li>
  <li>A <code class="highlighter-rouge">SenderState</code> pointer which is a virtual base opaque structure
used to hold state associated with the packet but specific to the
sending device (e.g., an MSHR). A pointer to this state is returned
in the packet’s response so that the sender can quickly look up the
state needed to process it. A specific subclass would be derived
from this to carry state specific to a particular sending device.</li>
  <li>A <code class="highlighter-rouge">CoherenceState</code> pointer which is a virtual base opaque structure
used to hold coherence-related state. A specific subclass would be
derived from this to carry state specific to a particular coherence
protocol.</li>
  <li>A pointer to the request.</li>
</ul>

<h3 id="access-types">Access Types</h3>

<p>There are three types of accesses supported by the ports.</p>

<ol>
  <li><strong>Timing</strong> - Timing accesses are the most detailed access. They
reflect our best effort for realistic timing and include the
modeling of queuing delay and resource contention. Once a timing
request is successfully sent at some point in the future the device
that sent the request will either get the response or a NACK if the
request could not be completed (more below). Timing and Atomic
accesses can not coexist in the memory system.</li>
  <li><strong>Atomic</strong> - Atomic accesses are a faster than detailed access. They
are used for fast forwarding and warming up caches and return an
approximate time to complete the request without any resource
contention or queuing delay. When a atomic access is sent the
response is provided when the function returns. Atomic and timing
accesses can not coexist in the memory system.</li>
  <li><strong>Functional</strong> - Like atomic accesses functional accesses happen
instantaneously, but unlike atomic accesses they can coexist in the
memory system with atomic or timing accesses. Functional accesses
are used for things such as loading binaries, examining/changing
variables in the simulated system, and allowing a remote debugger to
be attached to the simulator. The important note is when a
functional access is received by a device, if it contains a queue of
packets all the packets must be searched for requests or responses
that the functional access is effecting and they must be updated as
appropriate. The <code class="highlighter-rouge">Packet::intersect()</code> and <code class="highlighter-rouge">fixPacket()</code> methods can
help with this.</li>
</ol>

<h3 id="packet-allocation-protocol">Packet allocation protocol</h3>

<p>The protocol for allocation and deallocation of Packet objects varies
depending on the access type. (We’re talking about low-level C++
<code class="highlighter-rouge">new</code>/<code class="highlighter-rouge">delete</code> issues here, not anything related to the coherence
protocol.)</p>

<ul>
  <li><em>Atomic</em> and <em>Functional</em> : The Packet object is owned by the
requester. The responder must overwrite the request packet with the
response (typically using the <code class="highlighter-rouge">Packet::makeResponse()</code> method).
There is no provision for having multiple responders to a single
request. Since the response is always generated before
<code class="highlighter-rouge">sendAtomic()</code> or <code class="highlighter-rouge">sendFunctional()</code> returns, the requester can
allocate the Packet object statically or on the stack.</li>
  <li><em>Timing</em> : Timing transactions are composed of two one-way messages,
a request and a response. In both cases, the Packet object must be
dynamically allocated by the sender. Deallocation is the
responsibility of the receiver (or, for broadcast coherence packets,
the target device, typically memory). In the case where the receiver
of a request is generating a response, it <em>may</em> choose to reuse the
request packet for its response to save the overhead of calling
<code class="highlighter-rouge">delete</code> and then <code class="highlighter-rouge">new</code> (and gain the convenience of using
<code class="highlighter-rouge">makeResponse()</code>). However, this optimization is optional, and the
requester must not rely on receiving the same Packet object back in
response to a request. Note that when the responder is not the
target device (as in a cache-to-cache transfer), then the target
device will still delete the request packet, and thus the responding
cache must allocate a new Packet object for its response. Also,
because the target device may delete the request packet immediately
on delivery, any other memory device wishing to reference a
broadcast packet past point where the packet is delivered must make
a copy of that packet, as the pointer to the packet that is
delivered cannot be relied upon to stay valid.</li>
</ul>

<h3 id="timing-flow-control">Timing Flow control</h3>

<p>Timing requests simulate a real memory system, so unlike functional and
atomic accesses their response is not instantaneous. Because the timing
requests are not instantaneous, flow control is needed. When a timing
packet is sent via <code class="highlighter-rouge">sendTiming()</code> the packet may or may not be accepted,
which is signaled by returning true or false. If false is returned the
object should not attempt to sent anymore packets until it receives a
<code class="highlighter-rouge">recvRetry()</code> call. At this time it should again try to call
<code class="highlighter-rouge">sendTiming()</code>; however the packet may again be rejected. Note: The
original packet does not need to be resent, a higher priority packet can
be sent instead. Once <code class="highlighter-rouge">sendTiming()</code> returns true, the packet may still
not be able to make it to its destination. For packets that require a
response (i.e. <code class="highlighter-rouge">pkt-&gt;needsResponse()</code> is true), any memory object can
refuse to acknowledge the packet by changing its result to <code class="highlighter-rouge">Nacked</code> and
sending it back to its source. However, if it is a response packet, this
can not be done. The true/false return is intended to be used for local
flow control, while nacking is for global flow control. In both cases a
response can not be nacked.</p>

<h3 id="response-and-snoop-ranges">Response and Snoop ranges</h3>

<p>Ranges in the memory system are handled by having devices that are
sensitive to an address range provide an implementation for
<code class="highlighter-rouge">getAddrRanges</code> in their slave port objects. This method returns an
<code class="highlighter-rouge">AddrRangeList</code> of addresses it responds to. When these ranges change
(e.g. from PCI configuration taking place) the device should call
<code class="highlighter-rouge">sendRangeChange()</code> on its slave port so that the new ranges are
propagated to the entire hierarchy. This is precisely what happens
during <code class="highlighter-rouge">init()</code>; all memory objects call <code class="highlighter-rouge">sendRangeChange()</code>, and a
flurry of range updates occur until everyones ranges have been
propagated to all busses in the system.</p>

  <br>

  <!-- RETRIVE PREVIOUS PAGE LINK -->
  
    
  
    
  
    
  
    
  

  <!-- RETRIEVE NEXT PAGE LINK -->
  
    
  
    
  
    
  
    
  


  <div class="navbuttons">
    
      <a href=""><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a>
    

    
      <a href=""><button type="button" class="btn btn-outline-primary">NEXT</button></a>
    
  </div>
</div>

	</main>
	<footer class="page-footer">
	<div class="container">
		<div class="row">

			<div class="col-12 col-sm-4">
				<p>gem5</p>
				<p><a href="/about">About</a></p>
				<p><a href="/publications">Publications</a></p>
				<p><a href="/contributing">Contributing</a></p>
				<p><a href="/governance">Governance</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Docs</p>
				<p><a href="/documentation">Documentation</a></p>
				<p><a href="http://gem5.org/Documentation">Old Documentation</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5">Source</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Help</p>
				<p><a href="/search">Search</a></p>
				<p><a href="/mailing_lists">Mailing Lists</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Website Source</a></p>
			<br></div>

		</div>
	</div>
</footer>


	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
	<script src="https://unpkg.com/commentbox.io/dist/commentBox.min.js"></script>

	<script>
	  // When the user scrolls down 20px from the top of the document, show the button
	  window.onscroll = function() {scrollFunction()};

	  function scrollFunction() {
	      if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) {
	          document.getElementById("myBtn").style.display = "block";
	      } else {
	          document.getElementById("myBtn").style.display = "none";
	      }
	  }

	  // When the user clicks on the button, scroll to the top of the document
	  function topFunction() {
	      document.body.scrollTop = 0;
	      document.documentElement.scrollTop = 0;
	  }

		import commentBox from 'commentbox.io';
		// or
		const commentBox = require('commentbox.io');
		// or if using the CDN, it will be available as a global "commentBox" variable.

		commentBox('my-project-id');

	</script>

</body>


</html>
